import javax.swing.*;
import javax.swing.plaf.FontUIResource;     //修改字体
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
////一元多项式的算法
public class Frame_1 {
    private JFrame jFrame=new JFrame("一元多项式运算");              //创建一个具有指定标题的窗口
    private JPanel jPanel=new JPanel();                                 //创建一个默创建可分割窗格认的空白面板。
    FontUIResource f = new FontUIResource("楷书", 3, 20);   //调整窗口的字体
    int buttonx=80,buttony=50,yy=50;                                     //按钮的宽，高
    JTextField jTextField1 = new JTextField("",30);//表达式1
    JTextField jTextField2 = new JTextField("",30);//表达式2         //创建了表达式文本框
    JTextField ans1=new JTextField("",30);//升序答案输出
    JTextField Faults=new JTextField("报错区域",buttonx*5*10);     //创建了报错区域的文本框
    int width_T=5*buttonx,height_T=50;                           //？？，height_T??
    String[] strings={                          //构建了一个字符串
            "0" , "1" , "2" , "3" , "4" ,
            "5" , "6" , "7" , "8" , "9" ,
            "." ,"x^" , "+" , "-" ,
            "<=", "c" , "="
    };
    JComboBox<String> opCombo = new JComboBox<>(new String[]{"+", "-", "*"});   //下拉列表框组件，其中的选项都是字符串，中间那个
    JButton[] buttons=new JButton[17];                                          //创建按钮，触发用户交互操作
    String str="";
    //数字，运算符按钮，文本框的设计
    //构造函数，用于初始化并设置图形用户界面（GUI）的框架窗口
    public Frame_1(){
        this.initButton();
        this.buttonListener();  //添加按钮的监听器。
        jFrame.add(jPanel);     //将分割窗格添加到框架窗口（jFrame）中。
        jFrame.setSize(width_T+18,height_T*5+buttony*6+40); //设置框架窗口的大小为 width_T+18 的宽度和 height_T*6+buttony*6+40 的高度。
        jFrame.setLocationRelativeTo(null);//位置为显示器的正中间
        jFrame.addWindowListener(new WindowAdapter() {      //添加窗口监听器，当窗口被关闭时，执行相关的操作。
            @Override
            public void windowClosing(WindowEvent e) {
                jFrame.dispose();                           //释放窗口资源，关闭窗口
            }
        });
        jFrame.setResizable(false);//大小不能修改         //设置框架窗口为不可改变大小。
        jFrame.setVisible(true);                        //将框架窗口设置为可见状态，显示在屏幕上。
    }
    public void initButton(){                   //按钮组件加入容器里面
        this.SetButtons();              //创建
        jPanel.add(Faults);             //创建报错区域 面板
        jPanel.add(jTextField1);        //表达式1
        jPanel.add(jTextField2);        //表达式2
//下拉列表框组件
        opCombo.setBounds(width_T/2-10,height_T*3,50,40);      //位置，宽，高
        opCombo.setFont(f);     //字体
        jPanel.add(opCombo);    //添加下拉列表框组件面板
        jPanel.add(ans1);       //创建升序答案面板
        for (int i = 0; i < buttons.length; i++) {      //添加按钮
            jPanel.add(buttons[i]);
        }
        jPanel.setLayout(null);//自定义设置
    }
    public void buttonListener(){
        int k=0;
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //getSelectedTextField 方法根据两个文本框对象的焦点状态，确定哪一个文本框当前被选中。如果 textField1 获得了焦点，则返回 textField1 对象；如果 textField2 获得了焦点，
                //则返回 textField1 对象；如果 textField2 获得了焦点，则返回 textField2 对象；如果两个文本框都没有焦点，或者有其他情况，则返回 null。
                JTextField selectedTextField = getSelectedTextField(jTextField1, jTextField2);
                if(selectedTextField!=null){
                    selectedTextField.setText(selectedTextField.getText()+"0");
                }
            }
        });
        //如此重复14次（10个数字，.幂，+,-）
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JTextField selectedTextField = getSelectedTextField(jTextField1, jTextField2);
                if(selectedTextField!=null){
                    selectedTextField.setText(selectedTextField.getText()+"1");
                }       //当这个按钮被点击时，如果存在选中的文本框，就会在该文本框中追加字符"1"
            }
        });
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JTextField selectedTextField = getSelectedTextField(jTextField1, jTextField2);
                if(selectedTextField!=null){
                    selectedTextField.setText(selectedTextField.getText()+"2");
                }
            }
        });
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JTextField selectedTextField = getSelectedTextField(jTextField1, jTextField2);
                if(selectedTextField!=null){
                    selectedTextField.setText(selectedTextField.getText()+"3");
                }
            }
        });
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JTextField selectedTextField = getSelectedTextField(jTextField1, jTextField2);
                if(selectedTextField!=null){
                    selectedTextField.setText(selectedTextField.getText()+"4");
                }
            }
        });
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JTextField selectedTextField = getSelectedTextField(jTextField1, jTextField2);
                if(selectedTextField!=null){
                    selectedTextField.setText(selectedTextField.getText()+"5");
                }
            }
        });
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JTextField selectedTextField = getSelectedTextField(jTextField1, jTextField2);
                if(selectedTextField!=null){
                    selectedTextField.setText(selectedTextField.getText()+"6");
                }
            }
        });
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JTextField selectedTextField = getSelectedTextField(jTextField1, jTextField2);
                if(selectedTextField!=null){
                    selectedTextField.setText(selectedTextField.getText()+"7");
                }
            }
        });
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JTextField selectedTextField = getSelectedTextField(jTextField1, jTextField2);
                if(selectedTextField!=null){
                    selectedTextField.setText(selectedTextField.getText()+"8");
                }
            }
        });
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JTextField selectedTextField = getSelectedTextField(jTextField1, jTextField2);
                if(selectedTextField!=null){
                    selectedTextField.setText(selectedTextField.getText()+"9");
                }
            }
        });
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JTextField selectedTextField = getSelectedTextField(jTextField1, jTextField2);
                if(selectedTextField!=null){
                    selectedTextField.setText(selectedTextField.getText()+".");
                }
            }
        });
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JTextField selectedTextField = getSelectedTextField(jTextField1, jTextField2);
                if(selectedTextField!=null){
                    selectedTextField.setText(selectedTextField.getText()+"x^");
                }
            }
        });
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JTextField selectedTextField = getSelectedTextField(jTextField1, jTextField2);
                if(selectedTextField!=null){
                    selectedTextField.setText(selectedTextField.getText()+"+");
                }
            }
        });
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JTextField selectedTextField = getSelectedTextField(jTextField1, jTextField2);
                if(selectedTextField!=null){
                    selectedTextField.setText(selectedTextField.getText()+"-");
                }
            }
        });
// 退格符
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JTextField selectedTextField = getSelectedTextField(jTextField1, jTextField2);
                //删除运算符或者操作
                if(selectedTextField!=null){
                    String x=selectedTextField.getText();
                    if(x.length()>0){
                        char op=x.charAt(x.length()-1);
                        int sub=1;          //退几个
                        if(op=='^')
                            sub=2;
                        if(x.length()==sub)
                            x="";
                        else
                            x=x.substring(0,x.length()-sub);
                    }
                    selectedTextField.setText(x);
                }
            }
        });
        // C 清空
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JTextField selectedTextField = getSelectedTextField(jTextField1, jTextField2);
                if (selectedTextField != null) {
                    // 获取选中文本框的内容
                    String text = selectedTextField.getText();
                    // 添加输入内容到选中文本框
                    selectedTextField.setText("");
                }
            }
        });
        //＝
        //多项式的计算方法
        buttons[k++].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //这里获取答案/打印错误信息
                //如果这两个表达式正确
                if(Check(jTextField1.getText())&&Check(jTextField2.getText())){
                    Faults.setText("报错区域");             //？？？？
                    int i=opCombo.getSelectedIndex();   //getSelectedIndex用于获取选择框（下拉框）中当前选中项的索引值，获取是
                    String s="+-*";                     //+还是-还是*
                    //一元多项式的数据结构
                    polynomial p = new polynomial(s.charAt(i),jTextField1.getText(),jTextField2.getText());
                    ans1.setText(p.order);
                }
            }
        });
    }
    public void SetButtons(){
        for(int i=0;i<strings.length;i++){
            buttons[i]=new JButton(strings[i]);//可以外加设置字体   //创建一个带有指定文本的按钮
            buttons[i].setFont(f);                               //设置按钮的字体
            buttons[i].setFocusable(false);                      //设置按钮的背景颜色
        }   //false，这个按钮将无法被选中，用户无法通过键盘或鼠标对其进行操作。
        int k=0;
        for(int i = 0; i < 2; i++){                            //设置数字按钮的位置（x,y坐标），宽，高
            for (int j = 0; j < 5; j++) {                      //坐标是怎么算的？？？
                buttons[k++].setBounds(buttonx*j,5*height_T+yy*i+40,buttonx,buttony);
            }
        }
        for(int j=0;j<4;j++)                                   //设置一元多项式的运算符
            buttons[k++].setBounds(buttonx*j,5*height_T+yy*2+40,buttonx,buttony);
        for(int j=0;j<3;j++)                                   //设置一元多项式的运算符   <=
            buttons[k++].setBounds(buttonx*j,5*height_T+yy*3+40,buttonx,buttony);
//多行文本编辑框的设计
//报错区域 文本框
        Faults.setBounds(0,0,width_T,height_T);
        Faults.setText("报错区域");
        Faults.setFont(f);
        Faults.setHorizontalAlignment(JLabel.RIGHT);//文本靠右
        Faults.setEditable(false);//不可修改
        //Faults.setBackground(Color.GRAY);//颜色为灰色
//第一个表达式输入窗口
        jTextField1.setBounds(0,height_T,width_T,height_T);
        jTextField1.setFont(f);//设置字体的函数
        jTextField1.setHorizontalAlignment(JLabel.LEFT);//文本靠左
        jTextField1.setEditable(false);//不可修改
        jTextField1.setBackground(Color.WHITE);//颜色为白色
//第二个表达式输出窗口
        jTextField2.setBounds(0,height_T*2,width_T,height_T);
        jTextField2.setFont(f);//设置字体的函数
        jTextField2.setHorizontalAlignment(JLabel.LEFT);//文本靠右
        jTextField2.setEditable(false);//不可修改
        jTextField2.setBackground(Color.white);//颜色为白色
//升序输出窗口
        ans1.setBounds(0,height_T*3+40,width_T,height_T);
        ans1.setFont(f);//设置字体的函数
        ans1.setHorizontalAlignment(JLabel.LEFT);//文本靠右
        ans1.setEditable(false);//不可修改
        ans1.setBackground(Color.WHITE);//颜色为白色
    }

    //初始化按钮                 //在容器里面加入
    boolean Check(String s){            //表达式的检查
        int i=0;    //while一个一个扫描 文本框里的内容
        while(i<s.length()) {
            //检查表达式的末尾应为数字
            int flag = 1;       //charAt获取字符串中指定索引位置的字符
            if (s.charAt(i) == '-') {       //表示遇到负号了
                flag = -1;
                i++;
            } else if (s.charAt(i) == '+') {
                i++;
            }
            if(i==s.length()){              //表达式有误
                Faults.setText("表达式的末尾应为数字");
                return false;
            }
            //检查符号是否连续出现
            //indexOf 用于在字符串中搜索指定子串的第一个出现位置，并返回该位置的索引值
            //+-".indexOf(s.charAt(i)) 使用 indexOf() 方法来判断该字符在字符串 "+-" 中的位置，如果字符是 “+” 或 “-”，则返回值大于等于0。
            if("+-".indexOf(s.charAt(i))>=0){       //进行运算符连续性的检查。
                Faults.setText("运算符出现连续");      //如果出现连续的运算符（即相邻字符都是 “+” 或 “-”）
                return false;
            }
            //确定最后一位项数的位置
            int j = i; //从 i 开始遍历字符串 s 的字符，判断字符是否为 “+” 或 “-”，如果不是则增加 i 的值。这个循环用于确定最后一位项数的位置。
            while (i < s.length() && "+-".indexOf(s.charAt(i)) == -1) {
                i++;
            }
            //确定幂数的起始位置
            int k = j;  //用于记录幂数的起始索引。
            //从 k 开始遍历字符串 s 的字符，判断字符是否为 “+”、“-” 或 “x”，如果不是则增加 k 的值。这个循环用于确定幂数的起始位置。
            while (k < i && "+-x".indexOf(s.charAt(k))==-1) {
                k++;
            }
            //[j,k)是项数,k可能是x/+/-,如果k=x,那么[k+2,i]应该为整数（次幂）
            //检查小数点
            int count=0;//记录小数点，检查小数点的数量
            for(int x=j;x<k;x++){   //如果遇到小数点，则增加计数器 count 的值。
                if("0123456789".indexOf(s.charAt(x))>=0)continue;
                count++;
            }       //如果 count 大于1，表示项数的小数点超过了一位，发出错误提示并返回 false。
            if(count>1){
                Faults.setText("项数的小数点只能有一位");
                return false;
            }
            //检查幂数部分
            if(k< s.length()&&s.charAt(k)=='x'){
                ////[j,k)是项数,k可能是x/+/-,如果k=x,那么[k+2,i]应该为整数（次幂）
                if(k+1==i||k+2==i){             //走到最后
                    Faults.setText("某一项缺少幂数");
                    return false;
                }
                if(s.charAt(k+2)=='0'&&k+3!=i){     //幂数 ，x的零次后不能有数字
                    Faults.setText("幂数出错");
                    return false;
                }
                for(int x=k+2;x<i;x++){
                    if(s.charAt(x)=='.'){
                        Faults.setText("幂数不能为小数");
                        return false;
                    }
                }
            }
        }
        return true;
    }
    private static JTextField getSelectedTextField(JTextField textField1, JTextField textField2) {
        //表示两个文本框对象
        if (textField1.hasFocus()) {        //检查是否被选中焦点 ，选中就返回改文本框对象
            return textField1;
        } else if (textField2.hasFocus()) {
            return textField2;
        } else {
            return null;
        }
    }
    public static void main(String[] args) {
        Frame_1 frameP=new Frame_1();
    }
}
